import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Avatar, Button, Checkbox, Flex, Input, List, message, Modal, Tree } from "antd";
import { forwardRef, useEffect, useImperativeHandle, useState, useRef, useMemo } from "react"
import { userSelectTree, searchDeptUserList } from '@/api/system/dept'
import { getUserInfoByIds } from '@/api/system/user'
import { SvgIcon } from "@/components/icon";
import { useThemeToken } from "@/theme/hooks";
import { expandTree } from "@/utils";
import { DeleteOutlined, UserOutlined, CloseCircleOutlined, DragOutlined } from '@ant-design/icons';
import styled from 'styled-components'
import { ReactSortable } from "react-sortablejs";

const SelectUserModal = forwardRef((props, ref) => {
  const { colorLink, colorBorder } = useThemeToken();
  const [loadedKeys, setLoadedKeys] = useState([])
  const [checkedKeys, setCheckedKeys] = useState([])
  const [checkedRows, setCheckedRows] = useState([])
  const [expandedKeys, setExpandedKeys] = useState([])
  const [isModalOpen, setIsModalOpen] = useState()
  const [queryParam, setQueryParam] = useState({
    searchText: ''
  });
  const [enabled, setEnabled] = useState(false)

  const queryClient = useQueryClient()

  const { data: treeOptions, isPending } = useQuery({
    queryKey: ['userSelectTree', queryParam],
    queryFn: () => {
      if (queryParam.searchText) {
        return searchDeptUserList(queryParam).then((response) => {
          setExpandedKeys(expandTree(response.data, 100))
          return response.data
        })
      } else {
        return userSelectTree('0', 3).then((response) => {
          setExpandedKeys(expandTree(response.data, 3))
          return response.data
        })
      }
    },
    staleTime: 0,
    enabled: enabled
  })
  useEffect(() => {
    if (isModalOpen) {
      if (!enabled) {
        setEnabled(true)
      } else {
        setExpandedKeys(expandTree(treeOptions, 3))
        setCheckedKeys([])
        setCheckedRows([])
      }
    }
  }, [isModalOpen])


  useImperativeHandle(ref, () => ({
    showModal: () => {
      setIsModalOpen(true)
    },
    checkedRows: checkedRows
  }));

  const mutation = useMutation({
    mutationFn: (param) => {
      return appModelApi(param)
    },
    onSuccess: () => {
      setIsModalOpen(false)
    }
  })

  const handleOk = () => {
    let rows = checkedRows.filter(d => d.isLeaf)
    if (rows.length > props.maxSelect && props.maxSelect !== 0) {
      message.warning(`已设置最多选择${props.maxSelect}人！`)
      return
    }
    props.onOk && props.onOk(checkedRows.filter(d => d.isLeaf))
    setIsModalOpen(false)
  };
  const handleCancel = () => {
    setIsModalOpen(false)
  };


  // 递归查找并更新节点
  const updateTreeNode = (treeData, key, newData) => {
    return treeData.map((node) => {
      if (node.id === key) {
        return { ...node, children: newData || [] };
      }
      if (node.children) {
        return { ...node, children: updateTreeNode(node.children, key, newData) };
      }
      return node;
    });
  };

  // 展开节点时动态加载数据
  const onLoadData = (treeNode) => {
    return userSelectTree(treeNode.id, 1).then(({ data: child = [] }) => {
      if (!loadedKeys.includes(treeNode.id)) {
        setLoadedKeys(val => (val.concat(treeNode.id)))
      }
      const nowTree = updateTreeNode(treeOptions, treeNode.key, child)
      queryClient.setQueryData(['userSelectTree', queryParam], nowTree)
      // 当前节点已经是选中状态时异步加载子节点的话，需要将子节点人员选择到已选人员列表
      let waitChild = child.filter(d => !checkedKeys.includes(d.id))
      if (waitChild.length && checkedKeys.includes(treeNode.id)) {
        setCheckedKeys(val => (val.concat(waitChild.map(d => d.id))))
        setCheckedRows(val => (val.concat(waitChild)))
      }
    })
  }

  const onCheck = (val, data) => {
    setCheckedKeys(val)
    setCheckedRows((ol) => {
      let olIds = ol.map(d => d.id)
      return ol.filter(d => val.includes(d.id)).concat(data.checkedNodes.filter(d => !olIds.includes(d.id)))
    })

    // 如果节点没有子节点，则手动加载
    if (!expandedKeys.includes(data.node.key) && val.includes(data.node.key)) {
      setExpandedKeys((ol) => [...ol, data.node.key]);
    }
  }

  // const updateCheckedRows = (data) =>{
  //   return
  // }

  const deleteSelectUser = (data) => {
    if (data === true) {
      setCheckedKeys([])
      setCheckedRows([])
    } else {
      let result = []
      let keys = [...checkedKeys]
      getParentId(data, treeOptions, result)
      result.map(item => {
        keys = keys.filter(its => its != item)
      })
      setCheckedKeys(keys)
      setCheckedRows(checkedRows.filter(its => keys.includes(its.id)))
    }
  }

  // 获取父级id
  const getParentId = (id, list = [], result = []) => {
    for (let i = 0; i < list.length; i += 1) {
      const item = list[i]
      if (item.key === id) {
        result.push(item.key)
        if (result.length === 1) return result
        return true
      }
      // 如果存在下级节点，则继续遍历
      if (item.children) {
        // 预设本次是需要的节点并加入到最终结果result中
        result.push(item.key)
        const find = getParentId(id, item.children, result)
        // 如果不是false则表示找到了，直接return，结束递归
        if (find) {
          return result
        }
        // 到这里，意味着本次并不是需要的节点，则在result中移除
        result.pop()
      }
    }
    // 如果都走到这儿了，也就是本轮遍历children没找到，将此次标记为false
    return false
  }

  return <Modal
    width={'70%'}
    styles={{
      content: { padding: 0 },
      header: { padding: '20px 24px 0' },
      footer: { padding: '0 24px 20px' },

    }}
    loading={isPending}
    title="人员选择"
    open={isModalOpen}
    confirmLoading={mutation.isPending}
    onOk={handleOk}
    onCancel={handleCancel}>
    <Flex style={{ borderBottom: `1px solid ${colorBorder}`, borderTop: `1px solid ${colorBorder}`, height: '380px' }}>
      <Flex vertical style={{ width: '50%', borderRight: `1px solid ${colorBorder}`, padding: '10px 15px', overflow: 'auto' }}>
        <Input.Search defaultValue={queryParam.searchText} style={{ marginBottom: '5px' }} allowClear placeholder="输入字符回车查询" onSearch={(v) => {
          setExpandedKeys([])
          setLoadedKeys([])
          setQueryParam({ searchText: v })
        }} />
        <Tree
          checkable
          loadedKeys={loadedKeys}
          expandedKeys={expandedKeys}
          checkedKeys={checkedKeys}
          fieldNames={{ title: 'title', key: 'id' }}
          treeData={treeOptions}
          loadData={onLoadData}
          onCheck={onCheck}
          onExpand={(expandedKeys) => {
            setExpandedKeys(expandedKeys)
          }}
          titleRender={({ title: text, slots }) => {
            return text
            let icon = 'connections'
            let iconProps = {
              icon: icon,
              size: '20',
              color: colorLink,
              style: {
                marginTop: '-4px', marginRight: '8px'
              }
            }
            if (!slots || !slots.icon) return text
            if (slots.icon === 'org') iconProps.icon = 'companyFill'
            if (slots.icon === 'company') iconProps.icon = 'company'
            if (slots.icon === 'user') iconProps.icon = 'users'
            if (text.indexOf(queryParam.searchText) > -1) {
              return <><SvgIcon {...iconProps} />
                {text.substr(0, text.indexOf(queryParam.searchText))}
                <span style={{ color: '#f50' }}> {queryParam.searchText} </span>
                {text.substr(text.indexOf(queryParam.searchText) + queryParam.searchText.length)}
              </>
            } else {
              return <><SvgIcon {...iconProps} />{text}</>
            }
          }}
        ></Tree>
      </Flex>
      <CheckedList listData={checkedRows.filter(d => d.isLeaf)} onChange={setCheckedRows} onDelete={deleteSelectUser} />
    </Flex>
  </Modal>
})


const CheckedList = ({ listData, onChange, onDelete }) => {
  const [checkAll, setCheckAll] = useState(false)
  const [selectUserIds, setSelectUserIds] = useState([])
  const indeterminate = useMemo(() => {
    return selectUserIds.length > 0 && selectUserIds.length != listData.length
  }, [selectUserIds, listData])

  const onCheckAllChange = () => {
    if (checkAll) {
      setCheckAll(false)
      setSelectUserIds([])
    } else {
      setCheckAll(true)
      setSelectUserIds(listData.map(item => item.id))
    }
  }
  const onCheckChange = (val) => {
    if (val.length === listData.length) {
      setCheckAll(true)
    }
    setSelectUserIds(val)
  }

  useEffect(() => {
    setSelectUserIds([])
    setCheckAll(false)
  }, [listData])


  return <StyledCheckedList>
    <Flex justify="space-between" align="center" style={{ padding: '10px 20px' }}>
      <Checkbox
        indeterminate={indeterminate}
        onChange={onCheckAllChange}
        checked={checkAll}>
        已选（{selectUserIds.length}）
      </Checkbox>

      <Button type="text" disabled={selectUserIds.length === 0} onClick={() => onDelete(true)} ><DeleteOutlined /></Button>
    </Flex>
    <Checkbox.Group
      value={selectUserIds}
      onChange={onCheckChange}
    >
      <ReactSortable
        className="list-wrap"
        animation={300}
        delay={100}
        chosenClass={'select-list-color'} // 被选中项的css 类名
        dragClass={'drag-list-color'} // 正在被拖拽中的css类名
        list={listData}
        setList={onChange}
      >
        {listData.map((item) => (
          <div key={item.id}>
            <div className="list-item">
              <div className="list-item-left">
                <Checkbox value={item.id}></Checkbox>
                <Avatar size={30} style={{ backgroundColor: '#47b5e6' }}><UserOutlined /></Avatar>
                <span className="title-name">{item.title}</span><span className="title-dept">({item.attributes.subtitle})</span>
              </div>
              <div className="list-item-right">
                <DragOutlined />
                <CloseCircleOutlined onClick={() => onDelete(item.id)} />
              </div>
            </div>
          </div>
        ))}
      </ReactSortable>
    </Checkbox.Group>
  </StyledCheckedList >
}

const StyledCheckedList = styled.div`
  display: flex;
  flex-direction: column;
  flex:1;
  width: '50%';
  overflow: 'auto';
  .title-dept{
    color: #a5a5a5;
    font-size: 12px;
    margin-left: 5px;
  }
  .ant-avatar{
    margin: 0 10px;
  }
  .list-wrap{
    margin: 0 10px;
    width: 100%;
  }
  .list-wrap .list-item{
    padding: 5px 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    transition: all .3s;
    cursor: all-scroll;
    &:hover{
      background-color: rgba(255, 255, 255, 0.08);
      .list-item-right{
        opacity: 1;
      }
    }
  }

  .list-item-right{
    opacity: 0;
    transition: all .3s;
  }

  .anticon{
    padding: 4px;
    cursor: pointer;
    font-size: 16px;
  }

  .select-list-color {
    box-shadow: 0 2px 5px rgba(255, 255, 255, 0.2);
    z-index: 9999;
  }

  .drag-list-color {
    background-color: #007fff;
}
`
export default SelectUserModal